﻿using System;
using System.Net.Sockets;
using System.Windows.Forms;

namespace ChatClient
{
	public partial class MainForm : Form
	{
		private readonly Client _client = new Client();
		private readonly Timer _timer = new Timer();

		public MainForm()
		{
			InitializeComponent();
			_client.OnHelloResponse += HelloResponseHandler;
			_client.OnMessagesReceived += OnMessagesReceivedHandler;
			_client.OnClientListReceived += ClientListReceivedHandler;
			_timer.Interval = 1000;
			_timer.Tick += TimerTickHandler;
			_timer.Start();
		}

		private void TimerTickHandler(object sender, EventArgs eventArgs)
		{
			if (_client.Connected)
			{
				_client.GetClientList();
				_client.GetMessages();
			}
		}

		private void ClientListReceivedHandler(object sender, ClientListReceivedEventArgs e)
		{
			if (_userList.InvokeRequired)
			{
				Invoke(new Client_OnClientListReceivedDelegate(ClientListReceivedHandler), new[] {sender, e});
			}
			else
			{
				_userList.Items.Clear();
				foreach (string s in e.Users)
				{
					_userList.Items.Add(s);
				}
			}
		}

		private void OnMessagesReceivedHandler(object sender, MessagesReceivedEventArgs e)
		{
			if (_chatTextBox.InvokeRequired)
			{
				Invoke(new Client_OnMessagesReceivedDelegate(OnMessagesReceivedHandler), new[] {sender, e});
			}
			else
			{
				foreach (string s in e.Messages)
				{
					_chatTextBox.AppendText(s + "\n");
				}
			}
		}


		private void HelloResponseHandler(object sender, HelloResponseEventArgs e)
		{
			if (_chatTextBox.InvokeRequired)
			{
				Invoke(new Client_OnHelloResponseDelegate(HelloResponseHandler), new[] {sender, e});
			}
			else
			{
				if (e.Accepted)
				{
					_chatTextBox.AppendText("Connected to " + _client.Host + "\n");
				}
				else
				{
					_chatTextBox.AppendText("Server denied connection\n");
				}
			}
		}

		private void label1_Click(object sender, EventArgs e)
		{
		}

		private void ServerList_SelectedIndexChanged(object sender, EventArgs e)
		{
			string name = _nameTextBox.Text;
			if (name == "")
			{
				MessageBox.Show("Name can't be empty!");
				return;
			}
			try
			{
				_client.Disconnect();
			}
			catch (SocketException ex)
			{
				statusStrip1.Text = ex.Message;
			}
			try
			{
				_client.Connect(_nameTextBox.Text, (String) _serverList.SelectedItem);
			}
			catch (Exception ex)
			{
				statusStrip1.Text = ex.Message;
			}
		}

		private void textBox1_TextChanged(object sender, EventArgs e)
		{
		}

		private void _refreshServersButton_Click(object sender, EventArgs e)
		{
			_serverList.Items.Clear();
			_serverList.Items.AddRange(Client.RequestServers());
		}

		private void MainForm_Load(object sender, EventArgs e)
		{
			_refreshServersButton_Click(this, e);
		}

		private void _sendMessageBox_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == 13) //enter
			{
				if (_sendMessageBox.Text != "")
				{
					_client.SendMessage(_sendMessageBox.Text);
					e.Handled = true;
					_sendMessageBox.Clear();
				}
			}
		}

		#region Nested type: Client_OnClientListReceivedDelegate

		private delegate void Client_OnClientListReceivedDelegate(object sender, ClientListReceivedEventArgs e);

		#endregion

		#region Nested type: Client_OnHelloResponseDelegate

		private delegate void Client_OnHelloResponseDelegate(object sender, HelloResponseEventArgs e);

		#endregion

		#region Nested type: Client_OnMessagesReceivedDelegate

		private delegate void Client_OnMessagesReceivedDelegate(object sender, MessagesReceivedEventArgs e);

		#endregion
	}
}